<script setup lang="ts">
import { computed } from "vue";

/**
 * @see {@link https://vuejs.org/api/sfc-script-setup.html#defineoptions}
 */

import { UploadFile } from "element-plus";
import {
  getUserPage,
  getUserForm,
  deleteUsers,
  addUser,
  updateUser,
  updateUserStatus,
  updateUserPassword,
  downloadTemplateApi,
  exportUser,
  importUser,
} from "@/api/system/user";
import { listDeptOptions } from "@/api/system/dept";
import { listRoleOptions } from "@/api/system/role";
import { getDicts } from "@/store/modules/dict";
import { UserForm, UserQuery, UserPageVO } from "@/api/system/user/types";
import { getDeptPullDown } from "@/api/common/project";

import { useScreen } from "@/store/modules/screen";

const screenStore = useScreen();
const mobile = computed(() => screenStore.device);
const screenHeight = computed(() => screenStore.screenHeight);
const screenWidth = ref(600);

defineOptions({
  name: "User",
  inheritAttrs: false,
});
function initScreen() {
  if (mobile.value === "mobile") {
    screenWidth.value = screenStore.screenWidth;
  } else {
    screenWidth.value = 450;
  }
}

const queryFormRef = ref(ElForm); // 查询表单
const userFormRef = ref(ElForm); // 用户表单

const loading = ref(false);
const ids = ref([]);
const total = ref(0);
const dialog = reactive<DialogOption>({
  visible: false,
  userId: false,
});

const queryParams = reactive<UserQuery>({
  pageNum: 1,
  pageSize: 10,
});
const userList = ref<UserPageVO[]>();

const formData = reactive<UserForm>({
  status: 1,
  gender: 1,
});

const rules = reactive({
  cardno: [
    { required: true, message: "用户名不能为空", trigger: "blur" },
  ],
  name: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
  nickname: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
  roleIds: [{ required: true, message: "用户角色不能为空", trigger: "blur" }],
  areaId: [{ required: true, message: "用户所属区域不能为空", trigger: "blur" }],
  email: [
    {
      pattern: /\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]+\.)+[A-Za-z]{2,14}/,
      message: "请输入正确的邮箱地址",
      trigger: "blur",
    },
  ],
  mobile: [
    { required: true, message: "手机号码不能为空", trigger: "blur" },
    {
      pattern: /^1[3456789]\d{9}$/,
      message: "请输入正确的手机号码",
      trigger: "blur",
    },
  ],
  confirmPassword: [{ required: true, trigger: "blur", validator: passwordBlur }],
  password: [{ required: true, message: "登录密码不能为空", trigger: "blur" }],
});

const searchDeptName = ref();
const deptList = ref<OptionType[]>();
const roleList = ref<OptionType[]>();
const importDialog = reactive<DialogOption>({
  title: "用户导入",
  visible: false,
});

function passwordBlur(rule: any, value: any, callback: any) {
  if (!value || value === undefined || value === "") {
    callback(new Error("确认密码不能为空"));
    return;
  } else {
    if (value != formData.password) {
      callback(new Error("两次密码不一致"));
    } else {
      callback();
    }
  }
}

/**
 * 导入选择的部门ID
 */
const importDeptId = ref<number>();
const excelFile = ref<File>();
const excelFilelist = ref<File[]>([]);

/**
 * 部门筛选
 */
function handleDeptFilter(value: string, data: any) {
  if (!value) {
    return true;
  }
  return data.label.indexOf(value) !== -1;
}

/**
 * 部门树节点
 */
function handleDeptNodeClick(data: { [key: string]: any }) {
  queryParams.deptId = data.value;
  handleQuery();
}

/**
 * 获取角色下拉列表
 */
async function getRoleOptions() {
  listRoleOptions().then((response) => {
    roleList.value = response.data;
  });
}

/**
 * 修改用户状态
 */
function handleStatusChange(row: { [key: string]: any }) {
  const text = row.status === 1 ? "启用" : "停用";
  ElMessageBox.confirm("确认要" + text + row.username + "用户吗?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(() => {
      return updateUserStatus(row.id, row.status);
    })
    .then(() => {
      ElMessage.success(text + "成功");
    })
    .catch(() => {
      row.status = row.status === 1 ? 0 : 1;
    });
}

/**
 * 查询
 */
function handleQuery() {
  loading.value = true;
  getUserPage(queryParams)
    .then(({ data }) => {
      userList.value = data.list;
      total.value = data.total;
			loading.value = false;
    })
    .finally(() => {
    });
}

/**
 * 重置查询
 */
function resetQuery() {
  queryFormRef.value.resetFields();
  queryParams.pageNum = 1;
  queryParams.deptId = undefined;
  queryParams.status = undefined;
  handleQuery();
}

/**
 * 行checkbox change事件
 */
function handleSelectionChange(selection: any) {
  ids.value = selection.map((item: any) => item.userId);
}

/**
 * 重置密码
 */
function resetPassword(row: { [key: string]: any }) {
  ElMessageBox.prompt("请输入用户「" + row.name + "」的新密码", "重置密码", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
  })
    .then(({ value }) => {
      if (!value) {
        ElMessage.warning("请输入新密码");
        return false;
      }
      updateUserPassword(row.userId, value).then(() => {
        ElMessage.success("密码重置成功，新密码是：" + value);
      });
    })
    .catch(() => {});
}

/**
 * 打开用户弹窗
 */
async function openDialog(userId?: number) {
  await getRoleOptions();
  dialog.visible = true;
  if (userId) {
    dialog.userId = true;
    dialog.title = "修改用户";
    getUserForm(userId).then(({ data }) => {
      data.roleIds = data.roleIds[0];
      Object.assign(formData, data);
    });
  } else {
    dialog.userId = false;
    formData.userId = 0;
    dialog.title = "新增用户";
  }
}

/**
 * 关闭弹窗
 */
function closeDialog() {
  dialog.visible = false;
  resetForm();
}

/**
 * 重置表单
 */
function resetForm() {
  userFormRef.value.resetFields();
  userFormRef.value.clearValidate();

  formData.userId = undefined;
  formData.status = 1;
}

/**
 * 表单提交
 */
const handleSubmit = useThrottleFn(() => {
  userFormRef.value.validate((valid: any) => {
    if (valid) {
      const userId = formData.userId;
      loading.value = true;
      if (userId) {
        formData.roleIds = [formData.roleIds];
        updateUser(userId, formData)
          .then((resp) => {
            if (resp.success === true) {
              ElMessage.success(resp.msg);
              closeDialog();
              resetQuery();
            } else {
              ElMessage.warning(resp.msg);
            }
          })
      } else {
        formData.roleIds = [formData.roleIds];
        addUser(formData)
          .then((resp) => {
            if (resp.success === true) {
              ElMessage.success(resp.msg);
              closeDialog();
              resetQuery();
            } else {
              ElMessage.warning(resp.msg);
            }
          })
      }
    }
  });
}, 3000);

/**
 * 删除用户
 */
function handleDelete(userId?: number) {
  const userIds = [userId || ids.value].join(",");
  if (!userIds) {
    ElMessage.warning("请勾选删除项");
    return;
  }

  ElMessageBox.confirm("确认删除用户?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(function () {
      deleteUsers(userIds).then(() => {
        ElMessage.success("删除成功");
        resetQuery();
      });
    })
    .catch(() => {
      ElMessage({
        type: "info",
        message: "已取消！",
      });
    });
}

/**
 * 获取部门下拉项
 */
async function getDeptOptions() {
  listDeptOptions().then((response) => {
    deptList.value = response.data;
  });
}

/**
 * 下载导入模板
 */
function downloadTemplate() {
  downloadTemplateApi().then((response: any) => {
    const blob = new Blob([response.data], {
      type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8",
    });
    const a = document.createElement("a");
    const href = window.URL.createObjectURL(blob); // 下载链接
    a.href = href;
    a.download = decodeURI(response.headers["content-disposition"].split(";")[1].split("=")[1]); // 获取后台设置的文件名称
    document.body.appendChild(a);
    a.click(); // 点击下载
    document.body.removeChild(a); // 下载完成移除元素
    window.URL.revokeObjectURL(href); // 释放掉blob对象
  });
}

/**
 * 打开导入弹窗
 */
async function openImportDialog() {
  importDeptId.value = undefined;
  importDialog.visible = true;
}

//选择所属区域
const handelAreaChange = (val: any) => {
  let industryType = 0;
  if (formData.roleIds) {
    industryType = roleList.value.find((item: any) => item.value === formData.roleIds).extend1;
  }
  if (formData.roleIds && formData.areaId && industryType > 0) {
    getDeptPullDown({ industryType: industryType, areaCode: formData.areaId }).then((res) => {
      if (res.success) {
        if (res.data.length > 0) {
          formData.deptId = res.data[0].value;
        } else {
          formData.deptId = undefined;
        }
      }
    });
  }

  console.log(val);
};

/**
 * Excel文件change事件
 *
 * @param file
 */
function handleExcelChange(file: UploadFile) {
  if (!/\.(xlsx|xls|XLSX|XLS)$/.test(file.name)) {
    ElMessage.warning("上传Excel只能为xlsx、xls格式");
    excelFile.value = undefined;
    excelFilelist.value = [];
    return false;
  }
  excelFile.value = file.raw;
}

/**
 * 导入用户提交
 */
function handleUserImport() {
  if (importDeptId.value) {
    if (!excelFile.value) {
      ElMessage.warning("上传Excel文件不能为空");
      return false;
    }
    importUser(importDeptId.value, excelFile.value).then((response) => {
      ElMessage.success(response.data);
      closeImportDialog();
      resetQuery();
    });
  }
}

/**
 * 关闭导入弹窗
 */
function closeImportDialog() {
  importDialog.visible = false;
  excelFile.value = undefined;
  excelFilelist.value = [];
}

/**
 * 导出用户
 */
function handleUserExport() {
  exportUser(queryParams).then((response: any) => {
    const blob = new Blob([response.data], {
      type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8",
    });
    const a = document.createElement("a");
    const href = window.URL.createObjectURL(blob); // 下载的链接
    a.href = href;
    a.download = decodeURI(response.headers["content-disposition"].split(";")[1].split("=")[1]); // 获取后台设置的文件名称
    document.body.appendChild(a);
    a.click(); // 点击导出
    document.body.removeChild(a); // 下载完成移除元素
    window.URL.revokeObjectURL(href); // 释放掉blob对象
  });
}
const areaOptions = getDicts("areaTrees").filter((item) => item.value == "540000");
onMounted(() => {
  initScreen();

  getDeptOptions();
  handleQuery(); // 初始化用户列表数据
});
</script>

<script lang="ts">
export default {
  name: "User",
};
</script>

<template>
  <div class="app-container">
    <div class="search-container">
      <el-form ref="queryFormRef" :model="queryParams" :inline="true">
        <el-form-item label="关键字" prop="keywords">
          <el-input
            v-model="queryParams.keywords"
            placeholder="请输入关键字"
            clearable
            style="width: 200px"
            @keyup.enter="handleQuery"
          />
        </el-form-item>

        <el-form-item label="状态" prop="status">
          <el-select v-model="queryParams.status" placeholder="全部" clearable style="width: 200px">
            <el-option label="正常" value="1" />
            <el-option label="离岗" value="2" />
            <el-option label="封禁" value="3" />
          </el-select>
        </el-form-item>
        <el-form-item label="所属部门">
          <el-select v-model="queryParams.deptId" placeholder="全部" clearable>
            <el-option v-for="item in deptList" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handleQuery"><i-ep-search />搜索</el-button>
          <el-button @click="resetQuery">
            <i-ep-refresh />
            重置</el-button
          >
        </el-form-item>
      </el-form>
    </div>

    <el-card shadow="never">
      <template #header>
        <div class="flex justify-between">
          <div>
            <el-button v-hasPerm="['sys:user:add']" type="success" @click="openDialog()"><i-ep-plus />新增</el-button>
            <el-button
              v-hasPerm="['sys:user:delete']"
              type="danger"
              :disabled="ids.length === 0"
              @click="handleDelete()"
              ><i-ep-delete />删除</el-button
            >
          </div>
        </div>
      </template>

      <el-table
        v-loading="loading"
        :data="userList"
        highlight-current-row
        border
        @selection-change="handleSelectionChange"
      >
        <el-table-column type="selection" width="50" align="center" />
        <el-table-column key="name" label="姓名" align="center" prop="name" />
        <el-table-column key="cardNo" label="用户名" align="center" width="200" prop="cardNo" />
        <el-table-column key="genderName" label="性别" width="60" align="center" prop="genderName" />
        <el-table-column key="mobile" label="手机号" align="center" prop="mobile" />
        <el-table-column key="email" label="电子邮箱" align="center" prop="email" />
        <el-table-column key="roleName" label="所属角色" align="center" prop="roleName" />
        <el-table-column label="状态" align="center" width="80">
          <template #default="scope">
            <el-tag v-if="scope.row.statusName === '正常'" type="success">正常</el-tag>
            <el-tag v-if="scope.row.statusName === '离岗'" type="warning">离岗</el-tag>
            <el-tag v-if="scope.row.statusName === '封禁'" type="danger">封禁</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="创建时间" align="center" prop="createTime"></el-table-column>
        <el-table-column label="操作" fixed="right" :width="mobile === 'mobile' ? 100 : 220">
          <template #default="scope">
            <el-button
              v-hasPerm="['sys:user:reset_pwd']"
              type="primary"
              size="small"
              link
              @click="resetPassword(scope.row)"
              ><i-ep-refresh-left />重置密码</el-button
            >
            <el-button
              v-hasPerm="['sys:user:edit']"
              type="primary"
              link
              size="small"
              @click="openDialog(scope.row.userId)"
              ><i-ep-edit />编辑</el-button
            >
            <el-button
              v-hasPerm="['sys:user:delete']"
							v-if="scope.row.cardNo != 'admin'"
              type="primary"
              link
              size="small"
              @click="handleDelete(scope.row.userId)"
              ><i-ep-delete />删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>

      <pagination
        v-if="total > 0"
        v-model:total="total"
        v-model:page="queryParams.pageNum"
        v-model:limit="queryParams.pageSize"
        @pagination="handleQuery"
      />
    </el-card>

    <!-- 表单弹窗 -->
    <el-dialog
      v-model="dialog.visible"
      :width="screenWidth"
      :fullscreen="mobile === 'mobile'"
      class="system"
      :style="{ '--mobileAddFormHeight': mobile === 'mobile' ? screenHeight - 117 + 'px' : 'auto' }"
      :title="dialog.title"
      append-to-body
      draggable
      close-icon="CloseBold"
      @close="closeDialog"
    >
      <el-form
        ref="userFormRef"
        v-loading="loading"
        :model="formData"
        :rules="rules"
        label-width="100px"
        :inline="true"
      >
        <!-- <el-form-item label="身份证号码" prop="cardNo">
          <el-input
            v-model="formData.cardNo"
            :readonly="!!formData.userId"
            placeholder="请输入身份证号码"
          />
        </el-form-item>    -->
        <el-form-item label="用户名" prop="cardno">
          <el-input v-model="formData.cardno" class="input300" placeholder="请输入用户名" />
        </el-form-item>
        <el-form-item label="姓名" prop="name">
          <el-input v-model="formData.name" class="input300" placeholder="请输入姓名" />
        </el-form-item>
        <el-form-item label="性别" prop="gender">
          <el-select v-model="formData.gender" placeholder="请选择" clearable>
            <el-option label="未知" :value="0" />
            <el-option label="男" :value="1" />
            <el-option label="女" :value="2" />
          </el-select>
        </el-form-item>
        <el-form-item label="手机号码" prop="mobile">
          <el-input v-model="formData.mobile" class="input300" placeholder="请输入手机号码" maxlength="11" />
        </el-form-item>
        <el-form-item label="角色" prop="roleIds">
          <el-select v-model="formData.roleIds" placeholder="请选择" clearable @change="handelAreaChange">
            <el-option v-for="item in roleList" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="所属地区" prop="areaId">
          <el-tree-select
            v-model="formData.areaId"
            placeholder="选择所属地区"
            :data="areaOptions"
            filterable
            check-strictly
            clearable
            :render-after-expand="false"
            @change="handelAreaChange"
          />
        </el-form-item>

        <el-form-item label="邮箱" prop="email">
          <el-input v-model="formData.email" class="input300" placeholder="请输入邮箱" maxlength="50" />
        </el-form-item>

        <el-form-item v-if="false || !dialog.userId" label="登录密码" prop="password">
          <el-input v-model="formData.password" class="input300" type="password" placeholder="请输入登录密码" />
        </el-form-item>

        <el-form-item v-if="false || !dialog.userId" label="确认密码" prop="confirmPassword">
          <el-input v-model="formData.confirmPassword" type="password" placeholder="请输入确认密码" class="input300" />
        </el-form-item>

        <el-form-item label="状态" prop="status">
          <el-radio-group v-model="formData.status">
            <el-radio :label="1">正常</el-radio>
            <el-radio :label="2">离岗</el-radio>
            <el-radio :label="3">封禁</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button v-loading="loading" type="primary" @click="handleSubmit">确 定</el-button>
          <el-button @click="closeDialog()">取 消</el-button>
        </div>
      </template>
    </el-dialog>

    <!-- 导入弹窗 -->
    <el-dialog
      v-model="importDialog.visible"
      :title="importDialog.title"
      width="600px"
      append-to-body
      close-icon="CloseBold"
      @close="closeImportDialog"
    >
      <el-form v-loading="loading" label-width="80px">
        <el-form-item label="部门">
          <el-tree-select v-model="importDeptId" placeholder="请选择部门" :data="deptList" filterable check-strictly />
        </el-form-item>

        <el-form-item label="Excel">
          <el-upload
            class="upload-demo"
            action=""
            drag
            :auto-upload="false"
            accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel"
            :file-list="excelFilelist"
            :on-change="handleExcelChange"
            :limit="1"
          >
            <el-icon class="el-icon--upload">
              <i-ep-upload-filled />
            </el-icon>
            <div class="el-upload__text">
              将文件拖到此处，或
              <em>点击上传</em>
            </div>
            <template #tip>
              <div class="el-upload__tip">xls/xlsx files</div>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button v-loading="loading" type="primary" @click="handleUserImport">确 定</el-button>
          <el-button @click="closeImportDialog">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>
<style lang="scss" scoped>
.el-form-item__label {
  width: 100px !important;
}

.input300 {
  width: 210px !important;
}
</style>
